﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.Entities.MasterData
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class FieldDistributionInstruction:InstructionBase
    {
        #region props
        private string _ConnStr;
        /// <summary></summary>
        public string ConnStr
        {
            get
            {
                return this._ConnStr;
            }
            set
            {
                this._ConnStr = value;
            }
        }

        private string _SchemaName;
        /// <summary></summary>
        public string SchemaName
        {
            get
            {
                return this._SchemaName;
            }
            set
            {
                this._SchemaName = value;
            }
        }

        private string _TableName;
        /// <summary></summary>
        public string TableName
        {
            get
            {
                return this._TableName;
            }
            set
            {
                this._TableName = value;
            }
        }

        private string _SQL;
        /// <summary></summary>
        public string SQL
        {
            get
            {
                return this._SQL;
            }
            set
            {
                this._SQL = value;
            }
        }

        private string _PkField;
        /// <summary></summary>
        public string PkField
        {
            get
            {
                return this._PkField;
            }
            set
            {
                this._PkField = value;
            }
        }

        private string _FieldName;
        /// <summary>
        /// number field
        /// </summary>
        public string FieldName
        {
            get
            {
                return this._FieldName;
            }
            set
            {
                this._FieldName = value;
            }
        }

        private string _BinField;
        /// <summary></summary>
        public string BinField
        {
            get
            {
                return this._BinField;
            }
            set
            {
                this._BinField = value;
            }
        }

        private int _BinCount;
        /// <summary></summary>
        public int BinCount
        {
            get
            {
                return this._BinCount;
            }
            set
            {
                this._BinCount = value;
            }
        }
        #endregion

        #region ctor
        /// <summary>
        /// 
        /// </summary>
        public FieldDistributionInstruction():base(Guid.Empty,Guid.Empty)
        {
            this._ConnStr = string.Empty;
            this._SchemaName = string.Empty;
            this._TableName = string.Empty;
            this._SQL = string.Empty;
            this._PkField = string.Empty;
            this._FieldName = string.Empty;
            this._BinField = string.Empty;
            this._BinCount = 10;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="componentID"></param>
        /// <param name="jobTicketID"></param>
        /// <param name="connStr"></param>
        /// <param name="schema"></param>
        /// <param name="tbl"></param>
        /// <param name="sql"></param>
        /// <param name="pkField"></param>
        /// <param name="fieldName"></param>
        /// <param name="binField"></param>
        /// <param name="binCount"></param>
        public FieldDistributionInstruction(Guid componentID, Guid jobTicketID,
            string connStr, string schema, string tbl, string sql,
            string pkField, string fieldName, string binField, int binCount) 
            : base(componentID, jobTicketID)
        {
            this._ConnStr = connStr;
            this._SchemaName = schema;
            this._TableName = tbl;
            this._SQL = sql;
            this._PkField = pkField;
            this._FieldName = fieldName;
            this._BinField = binField;
            this._BinCount = binCount;
        }
        #endregion

        #region Overrides of InstructionBase

        /// <summary>
        /// serialize settings to xml
        /// the function below is mainly for storing into database as serialized form instead of string
        /// </summary>
        public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = XmlDataUtil.AddElement(ref xDoc, parentNode, "Instruction");
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Type", this.GetType().FullName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ComponentID", this.OwnerComponentID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "WorkerID", this.OwnerWorkerInstanceID.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SubmitTime", this.SubmitTime.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StartTime", this.StartTime.ToString());

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ConnStr", this.ConnStr);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Schema", this.SchemaName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Table", this.TableName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Sql", this.SQL);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "PkField",this.PkField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FieldName", this.FieldName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "BinField", this.BinField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "BinCount", this.BinCount.ToString());

            return xNode;
        }

        /// <summary>
        /// instantiated from xml
        /// "&lt;Instructions&gt;&lt;Instruction&gt;&lt;/Instruction&gt;&lt;/Instruction&gt;", must
        /// instantiate from first child of root node
        /// </summary>
        public override InstructionBase Instantiate(XmlNode xNode)
        {
            if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
            {
                FieldDistributionInstruction instruction = new FieldDistributionInstruction();
                instruction.OwnerComponentID = new Guid(xNode.Attributes.GetNamedItem("ComponentID").Value);
                instruction.OwnerWorkerInstanceID = new Guid(xNode.Attributes.GetNamedItem("WorkerID").Value);
                instruction.SubmitTime = DateTime.Parse(xNode.Attributes.GetNamedItem("SubmitTime").Value);
                instruction.StartTime = DateTime.Parse(xNode.Attributes.GetNamedItem("StartTime").Value);

                instruction.ConnStr = XmlDataUtil.GetAttributeValue(xNode, "ConnStr", "");
                instruction.SchemaName = XmlDataUtil.GetAttributeValue(xNode, "Schema", "");
                instruction.TableName = XmlDataUtil.GetAttributeValue(xNode, "Table", "");
                instruction.SQL = XmlDataUtil.GetAttributeValue(xNode, "Sql", "");
                instruction.PkField = XmlDataUtil.GetAttributeValue(xNode, "PkField", "");
                instruction.FieldName = XmlDataUtil.GetAttributeValue(xNode, "FieldName", "");
                instruction.BinField = XmlDataUtil.GetAttributeValue(xNode, "BinField", "");
                instruction.BinCount = int.Parse(XmlDataUtil.GetAttributeValue(xNode, "BinCount", "10"));
                
                return instruction;
            }
            else
            {
                throw new Exception("Unable to instantiate instruction: invalid type specified in xml node");
            }
        }

        #endregion
    }
}
